package com.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hospital.entity.Medicine;
import com.hospital.mapper.MedicineMapper;
import com.hospital.service.MedicineService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 药品服务实现类
 *
 * @author Hospital Management System
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MedicineServiceImpl extends ServiceImpl<MedicineMapper, Medicine> implements MedicineService {

    private final MedicineMapper medicineMapper;

    @Override
    public List<Medicine> getMedicines(String keyword) {
        return medicineMapper.getMedicines(keyword);
    }

    @Override
    public Map<String, Object> getMedicinesWithPagination(String keyword, Integer category, 
                                                          String ids, Integer page, Integer size) {
        // 创建分页对象
        Page<Medicine> pageObj = new Page<>(page, size);
        
        // 构建查询条件
        QueryWrapper<Medicine> wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", 0);
        
        // 如果提供了ids，优先按ids查询
        if (StringUtils.hasText(ids)) {
            List<String> idList = Arrays.asList(ids.split(","));
            wrapper.in("id", idList);
        } else {
            // 关键词搜索（药品名称或编码）
            if (StringUtils.hasText(keyword)) {
                wrapper.and(w -> w.like("name", keyword)
                                .or()
                                .like("medicine_code", keyword)
                                .or()
                                .like("generic_name", keyword));
            }
            
            // 分类筛选
            if (category != null) {
                wrapper.eq("category", category);
            }
        }
        
        // 按创建时间降序排列
        wrapper.orderByDesc("create_time");
        
        // 执行分页查询
        IPage<Medicine> pageResult = page(pageObj, wrapper);
        
        // 获取查询结果
        List<Medicine> medicines = pageResult.getRecords();
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", medicines);
        result.put("total", pageResult.getTotal());
        result.put("page", pageResult.getCurrent());
        result.put("size", pageResult.getSize());
        result.put("pages", pageResult.getPages());
        
        return result;
    }

    @Override
    public List<Medicine> getMedicinesByCategory(Integer category) {
        return medicineMapper.getMedicinesByCategory(category);
    }

    @Override
    public List<Medicine> getLowStockMedicines() {
        return medicineMapper.getLowStockMedicines();
    }

    @Override
    public List<Medicine> getNearExpiryMedicines() {
        return medicineMapper.getNearExpiryMedicines();
    }

    @Override
    public List<Medicine> getExpiredMedicines() {
        return medicineMapper.getExpiredMedicines();
    }

    @Override
    @Transactional
    public boolean addStock(Long medicineId, Integer quantity, String remark) {
        if (quantity <= 0) {
            throw new RuntimeException("入库数量必须大于0");
        }
        
        Medicine medicine = getById(medicineId);
        if (medicine == null) {
            throw new RuntimeException("药品不存在");
        }
        
        try {
            // 更新库存
            int result = medicineMapper.updateStock(medicineId, quantity);
            if (result > 0) {
                log.info("药品入库成功：{} 入库数量：{} 备注：{}", medicine.getName(), quantity, remark);
                
                // 更新药品状态
                Medicine updatedMedicine = getById(medicineId);
                if (updatedMedicine.getStockQuantity() > 0 && updatedMedicine.getStatus() == 2) {
                    // 如果原来是缺货状态，现在有库存了，更新为正常状态
                    updatedMedicine.setStatus(1);
                    updateById(updatedMedicine);
                }
                return true;
            } else {
                log.error("药品入库失败：{}", medicine.getName());
                return false;
            }
        } catch (Exception e) {
            log.error("药品入库异常：{}", e.getMessage(), e);
            throw new RuntimeException("药品入库失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean reduceStock(Long medicineId, Integer quantity, String remark) {
        if (quantity <= 0) {
            throw new RuntimeException("出库数量必须大于0");
        }
        
        Medicine medicine = getById(medicineId);
        if (medicine == null) {
            throw new RuntimeException("药品不存在");
        }
        
        if (medicine.getStockQuantity() < quantity) {
            log.warn("药品库存不足：{} 当前库存：{} 需要数量：{}", medicine.getName(), medicine.getStockQuantity(), quantity);
            return false;
        }
        
        // 减少库存
        int result = medicineMapper.reduceStock(medicineId, quantity);
        if (result > 0) {
            log.info("药品出库成功：{} 出库数量：{} 备注：{}", medicine.getName(), quantity, remark);
            
            // 检查库存状态
            Medicine updatedMedicine = getById(medicineId);
            if (updatedMedicine.getStockQuantity() <= 0) {
                // 库存为0，设置为缺货状态
                updatedMedicine.setStatus(2);
                updateById(updatedMedicine);
            }
            return true;
        } else {
            throw new RuntimeException("药品出库失败");
        }
    }

    @Override
    public Map<String, Object> getMedicineStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        // 药品总数统计
        QueryWrapper<Medicine> totalWrapper = new QueryWrapper<>();
        totalWrapper.eq("deleted", 0);
        long totalMedicines = count(totalWrapper);
        
        // 库存不足统计
        List<Medicine> lowStockMedicines = getLowStockMedicines();
        
        // 即将过期统计
        List<Medicine> nearExpiryMedicines = getNearExpiryMedicines();
        
        // 已过期统计
        List<Medicine> expiredMedicines = getExpiredMedicines();
        
        result.put("totalMedicines", totalMedicines);
        result.put("lowStockCount", lowStockMedicines.size());
        result.put("nearExpiryCount", nearExpiryMedicines.size());
        result.put("expiredCount", expiredMedicines.size());
        
        return result;
    }

    @Override
    public Map<String, Object> checkStockWarning() {
        Map<String, Object> warning = new HashMap<>();
        
        // 库存不足预警
        List<Medicine> lowStockMedicines = getLowStockMedicines();
        warning.put("lowStockMedicines", lowStockMedicines);
        warning.put("lowStockCount", lowStockMedicines.size());
        
        // 即将过期预警
        List<Medicine> nearExpiryMedicines = getNearExpiryMedicines();
        warning.put("nearExpiryMedicines", nearExpiryMedicines);
        warning.put("nearExpiryCount", nearExpiryMedicines.size());
        
        // 已过期预警
        List<Medicine> expiredMedicines = getExpiredMedicines();
        warning.put("expiredMedicines", expiredMedicines);
        warning.put("expiredCount", expiredMedicines.size());
        
        return warning;
    }

    @Override
    @Transactional
    public void updateMedicineStatus(Long medicineId, Integer status) {
        Medicine medicine = getById(medicineId);
        if (medicine != null) {
            medicine.setStatus(status);
            updateById(medicine);
            log.info("更新药品状态：{} 状态：{}", medicine.getName(), status);
        }
    }

    @Override
    @Transactional
    public void updateExpiredMedicineStatus() {
        QueryWrapper<Medicine> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("expiry_date", LocalDate.now())
                   .ne("status", 3); // 不是已过期状态的
        
        List<Medicine> expiredMedicines = list(queryWrapper);
        for (Medicine medicine : expiredMedicines) {
            medicine.setStatus(3); // 设置为过期状态
            updateById(medicine);
        }
        
        log.info("批量更新过期药品状态，共更新：{} 个药品", expiredMedicines.size());
    }

    @Override
    public List<Map<String, Object>> checkLowStock() {
        // 获取库存低于安全库存的药品
        QueryWrapper<Medicine> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", 0)
                   .apply("stock_quantity < safety_stock");
        
        List<Medicine> medicines = list(queryWrapper);
        
        // 构建预警信息
        return medicines.stream()
                .map(medicine -> {
                    Map<String, Object> warning = new HashMap<>();
                    warning.put("id", medicine.getId());
                    warning.put("title", "药品库存不足");
                    warning.put("description", 
                        String.format("%s库存仅剩%d%s，低于安全库存(%d%s)", 
                            medicine.getName(), 
                            medicine.getStockQuantity(),
                            medicine.getUnit(),
                            medicine.getSafetyStock(),
                            medicine.getUnit()));
                    warning.put("type", "warning");
                    return warning;
                })
                .collect(Collectors.toList());
    }
} 